var JSONStream = require('JSONStream');
var duplexer = require('duplexer');
var through = require('through');
var uglify = require('uglify-js');

var fs = require('fs');
var path = require('path');

var combineSourceMap = require('combine-source-map');
//合包文件里 有两处使用了 uglify 压缩， 一处是预加入前缀与后缀代码 ， 一处是模块源代码
function readPathFile(r,isCompress){
    //预编译里加入的对象源代码 压缩
    if(isCompress){
        return uglify(fs.readFileSync(path.join(__dirname, r), 'utf8'));
    }
    return fs.readFileSync(path.join(__dirname, r), 'utf8');
}

var prelude;

var finaleMaster;

var finaleSlave;

function contentInit(isCompress){
    prelude = readPathFile("prelude.js", isCompress);
    finaleMaster = readPathFile("finale-master.js", isCompress);
    finaleSlave = readPathFile("finale-slave.js", isCompress);
}

function newlinesIn(src) {
  if (!src) return 0;
  var newlines = src.match(/\n/g);

  return newlines ? newlines.length : 0;
}

module.exports = function (opts) {
    if (!opts) opts = {};
    var parser = opts.raw ? through() : JSONStream.parse([ true ]);
    var isMaster = opts.isMaster;
    var isCompress = opts.isCompress
    var output = through(write, end);
    parser.pipe(output);
    
    var first = true;
    var entries = [];
    /**
     * 行号 算入第一行
     * */
    var lineno = 1 + newlinesIn(prelude);
    var sourcemap;

    return duplexer(parser, output);

    function addPreText(){
        if(!first){
            return;
        }
        contentInit(isCompress);
        if(isMaster){
            this.queue(prelude + "\nRebrowser.classes = {");
        }else{
            this.queue("var mineClass = {");
        }
    }

    function write (row) {
        /**
         * 如果是第一行 则将 前缀加入
         * */
        addPreText.call(this);
        
        if (row.sourceFile) { 
            sourcemap = sourcemap || combineSourceMap.create();
            sourcemap.addFile(
                { sourceFile: row.sourceFile, source: row.source },
                { line: lineno }
            );
        }
        
        var wrappedSource = [
            (first ? '' : ','),
            JSON.stringify(row.id),
            ':[',
            'function(require,module,exports){\n',
            isCompress ? uglify(row.source) : row.source,    //模块内部源代码压缩
            '\n},',
            JSON.stringify(row.deps || {}),
            ']'
        ].join('');

        this.queue(wrappedSource);
        lineno += newlinesIn(wrappedSource);

        first = false;
        if (row.entry && row.order !== undefined) {
            entries[row.order] = row.id;
        }
        else if (row.entry) entries.push(row.id);
    }
    
    function end () {
        addPreText.call(this);
        entries = entries.filter(function (x) { return x !== undefined });
        var finaleText = finaleSlave;
        if(isMaster){
            finaleText = finaleMaster;
        }
        this.queue('};\n' + finaleText.replace("$es$",JSON.stringify(entries)));
        if (sourcemap) this.queue('\n' + sourcemap.comment());

        this.queue(null);
    }
};
